package serial.codec

import com.hontech.bvapp2.utils.isBitSet
import serial.toU8


class Uint8(var value: Int = 0) : CodecType {

    override fun size(): Int {
        return 1
    }

    override fun encode(buf: ByteArray, index: Int) {
        buf[index] = this.value.toByte()
    }

    override fun decode(buf: ByteArray, index: Int) {
        this.value = buf[index].toU8()
    }
}

class Uint16(var value: Int = 0) : CodecType {

    override fun size(): Int {
        return 2
    }

    override fun encode(buf: ByteArray, index: Int) {
        buf[index] = (this.value shr 8).toByte()
        buf[index + 1] = this.value.toByte()
    }

    override fun decode(buf: ByteArray, index: Int) {
        this.value = (buf[index].toU8() shl 8) + buf[index + 1].toU8()
    }

    fun signedValue(): Int {
        if (value.isBitSet(15)) {
            return -(0x10000 - value)
        }
        return value
    }
}

class Uint32(var value: Int = 0) : CodecType {

    override fun size(): Int {
        return 4
    }

    override fun encode(buf: ByteArray, index: Int) {
        buf[index] = (this.value shr 24).toByte()
        buf[index + 1] = (this.value shr 16).toByte()
        buf[index + 2] = (this.value shr 8).toByte()
        buf[index + 3] = this.value.toByte()
    }

    override fun decode(buf: ByteArray, index: Int) {
        this.value = (buf[index].toU8() shl 24) +
                (buf[index + 1].toU8() shl 16) +
                (buf[index + 2].toU8() shl 8) +
                buf[index + 3].toU8()
    }
}

fun Int.u8() = Uint8(this)
fun Int.u16() = Uint16(this)
fun Int.u32() = Uint32(this)


class FlexArray(val len: Int) : CodecType {

    private val data = ByteArray(len)

    fun getData(i: Int) = data[i].toU8()

    fun set(msg: String): FlexArray {
        val buf = msg.toByteArray()
        if (buf.size != len) {
            throw IllegalStateException("len != msg size")
        }
        System.arraycopy(buf, 0, data, 0, len)
        return this
    }

    override fun size(): Int {
        return len
    }

    override fun encode(buf: ByteArray, index: Int) {
        System.arraycopy(data, 0, buf, index, len)
    }

    override fun decode(buf: ByteArray, index: Int) {
        System.arraycopy(buf, index, data, 0, len)
    }

    override fun toString(): String {
        return String(data, 0, len)
    }

    fun toBCD(): String {
        val sb = StringBuilder()
        for (i in 0 until len) {
            val v = getData(i)
            val h = (v shr 4) and 0x0F
            val l = v and 0x0F
            sb.append("$h")
            sb.append("$l")
        }
        return sb.toString()
    }
}

